package com.xxgc.cloud.common.shiro.realm;

import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTHeader;
import cn.hutool.jwt.JWTUtil;
import com.xxgc.cloud.common.redis.RedisUtil;
import com.xxgc.cloud.common.shiro.config.JwtToken;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Set;

/*
 * @program: SpringCloudStudy
 * @description:
 * @author: Shijiayi
 * @create: 2022-12-08 11:56
 */
@Slf4j
@Component
public class UserRealm extends AuthorizingRealm {
    //注册中心获取
    @Value("${redis.login.key}")
    private String redisLoginKey;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    //去获取到授权的信息
    //权限
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String token = principalCollection.toString();
        //通过Token获取到uid

        final JWT jwt = JWTUtil.parseToken(token);
        jwt.getHeader(JWTHeader.TYPE);
        Integer uId = (Integer) jwt.getPayload("uid");
        log.info("token解析出uid"+uId);
        String redisKey = redisLoginKey+uId;
        String setRolesRedisKey = redisKey+"_roles";
        String setPermissionsRedisKey = redisKey+"_permissions";


        Set<Object> roles = redisUtil.membersSet(setRolesRedisKey);
        Set<String> rolesStr = new HashSet<>();
        for (Object role : roles) {
            rolesStr.add((String) role);
        }
        Set<Object> permissions = redisUtil.membersSet(setPermissionsRedisKey);
        Set<String> permissionsStr = new HashSet<>();
        for (Object permission : permissions) {
            permissionsStr.add((String) permission);
        }

        log.info("认证角色"+rolesStr.toString());
        log.info("认证权限"+permissionsStr.toString());
        //实例化授权对象
        SimpleAuthorizationInfo sai = new SimpleAuthorizationInfo();
        //添加权限
        sai.setStringPermissions(permissionsStr);
        //添加角色
        sai.setRoles(rolesStr);
        return sai;
    }

    //从数据库获取当前用户的账号、密码信息（认证）
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("认证-----------》》》》");
        log.info("1.toString ------>>> " + authenticationToken.toString());
        log.info("2.getCredentials ------>>> " + authenticationToken.getCredentials().toString());
        log.info("3. -------------》》 " +authenticationToken.getPrincipal().toString());
        String jwt = (String) authenticationToken.getCredentials();
//        if (!JwtUtils.verify(jwt)) {
//            throw new AuthenticationException("Token认证失败");
//        }
        return new SimpleAuthenticationInfo(jwt, jwt, "UserRealm");
    }
}
